<template>
  <div class="chat-app" @click="contextMenuVisible = false">
    <!-- 右键菜单 -->
    <div v-if="contextMenuVisible" class="context-menu" :style="{
      left: contextMenuPosition.x + 'px',
      top: contextMenuPosition.y + 'px'
    }">
      <div class="context-menu-item" @click="markAsUnread">标为未读</div>
      <div class="context-menu-item" @click="clearChatHistory">清空聊天记录</div>
    </div>
    <!-- 左侧主导航栏 -->
    <div class="main-sidebar">
      <div class="avatar">
        <div class="avatar-text">
          {{ userStore.username.charAt(0) }}
        </div>
      </div>
      <p class="avatar-name">
          {{ userStore.username }}
      </p>
      <div
        v-for="(item, index) in navItems"
        :key="index"
        class="nav-item"
        :class="{ active: currentNav === item.name }"
        @click="selectNav(item)"
      >
        <img v-if="item.icon" :src="item.icon" :alt="item.label">
        <span v-else-if="item.class" :class="item.class">退出登录</span>
      </div>
    </div>

    <!-- 好友列表侧边栏 -->
    <div class="friend-sidebar" v-if="currentNav === 'chat'">
      <div class="search-bar">
        <input
          v-model="searchQuery"
          type="text"
          placeholder="搜索"
          @input="handleSearch"
        >
      </div>
      <div class="friend-list" >
        <div
          v-for="friend in displayedFriends"
          :key="friend.id"
          class="friend-item"
          :class="{ active: currentChat.id === friend.id }"
          @click="selectChat(friend)"
          @contextmenu.prevent="showContextMenu($event, friend)"
        >
          <div class="friend-avatar">
            <div class="avatar-text">{{ friend.name.charAt(0) }}</div>
          </div>
          <div class="friend-info">
            <div class="friend-name">
              {{ friend.name }}
              <span v-if="isUserOnline(friend.id)" style="color: green;">在线</span>
            </div>
          </div>
          <span
            v-if="unreadCounts[friend.id] > 0"
            class="unread-badge"
          >
            {{ unreadCounts[friend.id] }}
          </span>
        </div>
      </div>
    </div>

    <div class="friend-sidebar" v-if="currentNav === 'contacts' || currentNav === 'add_group' ">
      <div class="search-bar">
        <input
          v-model="searchQuery"
          type="text"
          placeholder="搜索"
          @input="handleSearch"
        >
      </div>
      <div class="group-list">
        <div
          v-for="group in filteredGroups"
          :key="group.id"
          class="group-item"
          :class="{ active: currentGroup.id === group.id }"
          @click="selectGroup(group)"
        >
          <div class="group-avatar">
            <img :src="group.avatar" :alt="group.name">
          </div>
          <div class="group-info">
            <div class="group-name">{{ group.name }}</div>
          </div>
        </div>
      </div>
    </div>

<!-- 聊天区域 -->
<div class="chat-container" v-if="currentNav === 'chat'">
  <div class="chat-header">
    <div class="chat-title">{{ currentChat.name }}</div>
  </div>
  <div class="chat-messages" ref="messageContainer">
    <template v-for="(message, index) in currentMessages" :key="index">

      <!-- 显示时间 -->
      <div v-if="showMessageTime(message, index)" class="message-time">
        {{ formatMessageTime(message.time) }}
      </div>

      <!-- 渲染文件消息 -->
      <div v-if="message.messageType === 'FILE'" class="message" :class="message.type">
        <div class="message-avatar">
          <img :src="message.avatar" :alt="message.sender">
        </div>
        <div class="message-content">
          <div class="message-bubble">
            <div class="file-info">
              <p>文件：{{ message.content }}</p>
              <button @click="getFileData(message.content)">下载文件</button>
            </div>
          </div>
        </div>
      </div>

      <!-- 普通文本消息 -->
      <div v-else-if="message.messageType === 'TEXT'" class="message" :class="message.type">
        <div class="message-avatar">
          <div class="avatar-text">{{ message.sender.charAt(0) }}</div>
        </div>
        <div class="message-content">
          <div class="message-bubble">{{ message.content }}</div>
        </div>
      </div>

    </template>
  </div>

  <!-- 输入框区域 -->
  <div class="chat-input">
    <div class="input-toolbar">
      <button v-for="tool in tools" :key="tool.name" @click="handleToolClick(tool)">
        <img :src="tool.icon" :alt="tool.label">
      </button>
    </div>
    <div class="input-area">
      <textarea
        ref="messageInputRef"
        v-model="messageInput"
        placeholder="请输入消息..."
        @keydown.ctrl.enter="sendMessage('TEXT')"
      ></textarea>
      <button class="send-btn" @click="sendMessage('TEXT')">发送(S)</button>
    </div>
  </div>
</div>


        <!-- 群聊区域 -->
    <div class="chat-container" v-if="currentNav === 'contacts' || currentNav === 'add_group'">
    <div class="chat-header">
      <div class="chat-title">{{ currentGroup.name }}</div>
    </div>
    <div class="chat-messages" ref="messageContainer">
      <template v-for="(message, index) in currentMessages" :key="index">
          <div v-if="showMessageTime(message, index)" class="message-time">
            {{ formatMessageTime(message.time) }}
          </div>
          <div
            class="message"
            :class="message.type"
          >
            <!-- <div class="message-avatar">
              <img :src="message.avatar" :alt="message.sender">
            </div> -->
          <div class="message-avatar-container">
            <div class="message-avatar">
              <div class="avatar-text">{{ message.sender.charAt(0) }}</div>
            </div>
            <div class="message-sender">{{ message.sender }}</div>
          </div>
            <div class="message-content">
              <div v-if="message.messageType === 'TEXT'" class="message-bubble">{{ message.content }}</div>
              <div v-else-if="message.messageType === 'FILE'" class="message-bubble">
                <div class="file-info">
                  <p>文件：{{ message.content }}</p>
                  <button @click="getFileData(message.content)">下载文件</button>
                </div>
              </div>
            </div>
          </div>
        </template>
    </div>
    <div class="chat-input">
      <div class="input-toolbar">
        <button v-for="tool in tools" :key="tool.name" @click="handleToolClick(tool)">
          <img :src="tool.icon" :alt="tool.label">
        </button>
      </div>
      <div class="input-area">
        <textarea
          ref="messageInputRef"
          v-model="messageInput"
          placeholder="请输入消息..."
          @keydown.ctrl.enter="sendGroupMessage('TEXT')"
        ></textarea>
        <button class="send-btn" @click="sendGroupMessage('TEXT')">发送(S)</button>
      </div>
    </div>
    </div>

  </div>

  <!-- 点击按钮弹出添加群聊对话框 -->
<div @click="showAddGroupDialog">
  <img :src="navIcons.add_group" alt="添加群聊">
</div>

  <!-- 添加群聊对话框 -->
<div v-if="isAddGroupDialogVisible" class="add-group-dialog">
  <div class="dialog-content">
    <div class="group-avatar">
      <img :src="groupAvatar" alt="群头像">
    </div>
    <div class="group-name-input">
      <input v-model="groupName" type="text" placeholder="请输入群名">
    </div>
    <div class="dialog-footer">
      <button @click="handleConfirm">确认</button>
      <button @click="isAddGroupDialogVisible = false">取消</button>
    </div>
  </div>
</div>
<div v-if="showFileUploadModal" class="modal">
    <div class="modal-content">
      <span class="close-btn" @click="showFileUploadModal = false">&times;</span>
      <h3>文件上传</h3>
      <input type="file" @change="handleFileSelect" />
      <button @click="uploadFile" :disabled="!selectedFile">开始上传</button>
    </div>
  </div>
  <div v-if="showEmojiPicker" class="modal">
    <div class="modal-content">
      <span class="close-btn" @click="closeEmojiPicker">&times;</span>
      <h3>选择表情</h3>

      <!-- Emoji展示区域 -->
      <div class="emoji-grid">
        <span
          v-for="(emoji, index) in emojiList"
          :key="index"
          class="emoji-item"
          @click="selectEmoji(emoji)"
        >
          {{ emoji }}
        </span>
      </div>

      <!-- 底部操作按钮 -->
      <div class="action-buttons">
        <button @click="confirmSelection">确认选择</button>
        <button @click="closeEmojiPicker">取消</button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, nextTick } from 'vue'
import defaultAvatar from '@/assets/images/group.jpg';
import { useUserStore } from '../stores/user'
import { userIdStore } from '../utils/id';
import socket, { closeConnection } from '@/utils/socket'
import { useRouter } from 'vue-router'


// 添加群聊对话框相关状态
const isAddGroupDialogVisible = ref(false);  // 控制对话框显示
const groupName = ref('');  // 群名
const groupAvatar = ref('');  // 群头像
const userStore = useUserStore()
const idStore = userIdStore();
const router = useRouter();
const unreadCounts = reactive({})

// 右键菜单相关
const contextMenuVisible = ref(false)
const contextMenuPosition = reactive({
  x: 0,
  y: 0
})
const selectedFriend = ref(null)

const showContextMenu = (event, friend) => {
  event.preventDefault()
  contextMenuPosition.x = event.clientX
  contextMenuPosition.y = event.clientY
  contextMenuVisible.value = true
  selectedFriend.value = friend
}

const markAsUnread = () => {
  if (selectedFriend.value) {
    // 创建一个空消息用于标记未读
    const emptyMessage = {
      type: "SINGLE_MESSAGE",
      payload: {
        senderId: selectedFriend.value.id,
        targetId: idStore.id,
        content: null
      },
      timestamp: new Date().toISOString()
    }
    // 发送空消息到后端
    socket.send(JSON.stringify(emptyMessage))
    unreadCounts[selectedFriend.value.id] = 1
    contextMenuVisible.value = false
  }
}

const clearChatHistory = () => {
  if (selectedFriend.value && confirm('确定要清空与该好友的聊天记录吗？')) {
    const clearHistoryData = {
      type: "CLEAR_CHAT_HISTORY",
      payload: {
        senderId: idStore.id,
        targetId: selectedFriend.value.id
      },
      timestamp: new Date().toISOString()
    }
    socket.send(JSON.stringify(clearHistoryData))
    messages.value.set(selectedFriend.value.id, [])
    contextMenuVisible.value = false
  }
}

// 点击其他地方关闭右键菜单
onMounted(() => {
  document.addEventListener('click', () => {
    contextMenuVisible.value = false
  })
})

const SINGLE_MESSAGE_Data = ref({
  type: "SINGLE_MESSAGE",
  payload: {
    "senderId": "",
    "targetId": "",
    "content": "",
    'type': ""
  },
  timestamp: new Date().toISOString() // 确保时间戳有实际值
});

const HISTORIES_MESSAGE_Data = ref({
  type: "HISTORIES_MESSAGE",
  payload: {
    "senderId": "",
    "targetId": "",
  },
  timestamp: new Date().toISOString() // 确保时间戳有实际值
});

const histories_messages = ref([
  { id: 1, senderId: 1, targetId:2,content:"",time:""},
  { id: 2, senderId: 1, targetId:2,content:"",time:""},
])
socket.addEventListener('message', (event) => {
  if (typeof event.data === 'string'){
    // console.log('接收到的原始数据:', event.data);
     // 修复路径反斜杠问题
    let fixedData = event.data.replace(/\\/g, '\\\\'); // 将 \ 替换为 \\
    const response = JSON.parse(fixedData);
    console.log(response);
    if (response.responseMsg === "SINGLE_MESSAGE") {
      if (response.data.senderId === response.data.targetId) return;
      console.log("SINGLE_MESSAGE_SUCCESS");
      simulateResponse(response.data.content,response.data.senderId,response.data.type);
    }else if (response.responseMsg === "GET_USER_LIST_ACK") {
      friends.value = processUserList(response.data);
      console.log('更新后的好友列表:', friends.value);

      socket.send(JSON.stringify({
        type: 'GET_UNREAD_COUNTS',
        payload: { userId: parseInt(idStore.id) }
      }));
    }else if (response.responseMsg === "UNREAD_COUNTS") {
      Object.assign(unreadCounts, response.data);
    }else if (response.responseMsg === "HISTORIES_MESSAGE_ACK") {
      console.log("HISTORIES_MESSAGE_ACK");
      histories_messages.value = processHistoriesMessageList(response.data);
      setHistoriesMessage();
      console.log(histories_messages.value);
    } else if (response.responseMsg === "ROOM_MESSAGE_ACK") {
      console.log("ROOM_MESSAGE_ACK");
      //RoomMsgDTO(roomId=1, senderId=1, content=asdason)
      const groupMsg = response.data;
      getGroupMessage(groupMsg.roomId,groupMsg.senderId,groupMsg.content,groupMsg.type);
    }
    // 文件元数据处理
    else if (response.responseMsg === "file_meta") {
      console.log('收到元数据');
      fileDownloadState.value = {
        receiving: true,
        fileName: response.fileName,
        fileSize: response.fileSize,
        receivedSize: 0,
        chunks: [],
      }
    }
    else if (response.responseMsg === "ONLINE_USERS"){
      onlineUsers.value = response.data;
      console.log(22222222)
      console.log(onlineUsers.value)
    }
  }
  // 处理文件数据
  if (event.data instanceof ArrayBuffer) {
    if (!fileDownloadState.value.receiving) {
      console.warn('收到文件块但未开始接收，忽略数据')
      return
    }

    console.log('接收文件中...')

    // 记录数据块
    fileDownloadState.value.chunks.push(event.data)
    fileDownloadState.value.receivedSize += event.data.byteLength

    // 检查是否接收完成
    if (fileDownloadState.value.receivedSize >= fileDownloadState.value.fileSize) {
      downloadFile()
      fileDownloadState.value.receiving = false
    }
  }
});

const processHistoriesMessageList = (serverData) => {
    //数据转换
    return serverData
        .map(historiesMessage => ({
            id: parseInt(historiesMessage.id),      // 转换为数字类型
            senderId:parseInt(historiesMessage.senderId),
            targetId:parseInt(historiesMessage.targetId),
            content:historiesMessage.content,
            time:historiesMessage.time,
        }));
};
const setHistoriesMessage = () => {
  messages.value.clear();
  histories_messages.value.forEach((histories_message) => {
    const content = histories_message.content;
    const time = histories_message.time;
    // 如果消息内容为空或null，跳过该消息
    if (!content || content.trim() === '') return;
    if(parseInt(idStore.id) === histories_message.senderId)
  {
    const message = {
    type: 'sent',
    content:content,
    time: time,
    messageType: 'TEXT',
    sender: userStore.username,
    avatar: userAvatar.value
  }
  console.log("same id")
  const chatMessages = messages.value.get(currentChat.value.id) || []
  messages.value.set(currentChat.value.id, [...chatMessages, message])

  console.log(message);
}else{
    const message = {
      type: 'received',
      content: content,
      time: time,
      messageType: 'TEXT',
      sender: currentChat.value.name,
      avatar: currentChat.value.avatar
    }
    const sendMsgChat = ref(friends.value[0]);
    sendMsgChat.value = friends.value.find(friend => friend.id === histories_message.senderId);
    const chatMessages = messages.value.get(sendMsgChat.value.id) || []
    messages.value.set(sendMsgChat.value.id, [...chatMessages, message])

  }

});
  // 滚动到底部
  nextTick(() => {
    if (messageContainer.value) {
      messageContainer.value.scrollTop = messageContainer.value.scrollHeight
    }
  })
}

// 选择
const getHistoriesMessage = () => {
  if (socket.readyState === WebSocket.OPEN) {
    HISTORIES_MESSAGE_Data.value.payload.senderId = idStore.id;
    HISTORIES_MESSAGE_Data.value.payload.targetId = currentChat.value.id;
    socket.send(JSON.stringify(HISTORIES_MESSAGE_Data.value));
  } else {
    console.log("WebSocket 连接未就绪，等待连接...");
    socket.addEventListener('open', () => {
      getHistoriesMessage();
    });
  }

}
// 选择聊天对象
const selectChat = (friend) => {
  const currentChatElement = document.querySelector(`.friend-item.active`);
  if (currentChatElement) {
    currentChatElement.click(); // 触发点击事件
    console.log(`模拟点击当前聊天框: ${currentChat.value.name}`);
  }

  messageInput.value='';
  currentChat.value = friend

  unreadCounts[friend.id] = 0;

  if (!messages.value.has(friend.id)) {
    messages.value.set(friend.id, [])
  }

  console.log(friend.id);
  getHistoriesMessage();
}






const selectNav = (item) => {
  const previousNav = currentNav.value;

  if (item.name === 'logout') {
    // 弹出确认对话框
    if (confirm('确定要退出登录吗？')) {
      // 断开WebSocket连接
      closeConnection();
      // 调用store的登出方法
      userStore.logout();
      // 重定向到登录页面
      router.push('/login').then(() => {
      // 添加随机参数避免缓存
      window.location.href = '/login?t=' + Date.now()
    })
    } else {
      // 如果用户点击取消，恢复到之前的导航状态
      return;
    }
  }

  // 添加群聊和退出登录不改变导航状态
  if (item.name === 'add_group') {
    showAddGroupDialog()  // 显示添加群聊对话框
    return;
  }

  currentNav.value = item.name
  if (item.name === 'contacts') {
    // 选中第一个群聊
    selectGroup(groups.value[0]);
  }
}

// 用户信息
const userAvatar = ref(new URL('@/assets/images/libai.jpg', import.meta.url).href)

// 导航栏配置
const navIcons = {
  chat: {
    default: new URL('@/assets/icons/contacts1.png', import.meta.url).href,
    active: new URL('@/assets/icons/contacts2.png', import.meta.url).href
  },
  contacts: {
    default: new URL('@/assets/icons/group_chats.png', import.meta.url).href,
    active: new URL('@/assets/icons/group_chats2.png', import.meta.url).href
  },
  add_group:
     new URL('@/assets/icons/add_group.png', import.meta.url).href
  // 移除logout图标，将使用文字显示
}

const navItems = computed(() => [
  {
    name: 'chat',
    label: '聊天',
    icon: currentNav.value === 'chat' ? navIcons.chat.active : navIcons.chat.default
  },
  {
    name: 'contacts',
    label: '群聊',
    icon: currentNav.value === 'contacts' ? navIcons.contacts.active : navIcons.contacts.default
  },
  {
    name: 'add_group',
    label: '添加群聊',
    icon: navIcons.add_group
  },
  {
    name: 'logout',
    label: '退出登录',
    class: 'logout-text'
  }
])
const currentNav = ref('chat')



const GET_USER_LIST_Data = ref({
  type: "GET_USER_LIST",
  payload: {},
  timestamp: new Date().toISOString() // 确保时间戳有实际值
});
// get user list
const getUserList = () => {
  setTimeout(()=>{
    socket.send(JSON.stringify(GET_USER_LIST_Data.value));
  },200);
}
getUserList();

// 独立的数据处理函数
const processUserList = (serverData) => {
      //数据转换
    return serverData
        .filter(user => user.id && user.username) // 过滤无效数据
        .map(user => ({
            id: parseInt(user.id),      // 转换为数字类型
            name: user.username,        // 直接使用username作为name
        }));
};


// 工具栏配置
const tools = [
  { name: 'emoji', label: '表情', icon: new URL('@/assets/icons/expression.png', import.meta.url).href },
  { name: 'file', label: '文件', icon: new URL('@/assets/icons/file.png', import.meta.url).href },
  { name: 'image', label: '图片', icon: new URL('@/assets/icons/image.png', import.meta.url).href }
]

// 好友列表
const friends = ref([
  { id: 1, name: 'molidis', avatar: new URL('@/assets/images/libai.jpg', import.meta.url).href },
  { id: 2, name: 'ljw', avatar: new URL('@/assets/images/liuzongyuan.jpg', import.meta.url).href },
  { id: 3, name: '曾巩', avatar: new URL('@/assets/images/zenggong.jpg', import.meta.url).href },
  { id: 4, name: '秦始皇', avatar: new URL('@/assets/images/qinshihuang.jpg', import.meta.url).href },
  { id: 5, name: '刘备', avatar : new URL('@/assets/images/liubei.jpg', import.meta.url).href },
])

// 群聊列表
const groups = ref([
  { id: 1, name: '文学群', avatar: new URL('@/assets/images/shici.jpg', import.meta.url).href },
  { id: 2, name: '历史群', avatar: new URL('@/assets/images/lishi.jpg', import.meta.url).href },
  { id: 3, name: '科技群', avatar: new URL('@/assets/images/shici.jpg', import.meta.url).href },
])

// 搜索功能
const searchQuery = ref('')

// 当前用户 ID（从你的 idStore 拿）
const currentUserId = idStore.id

// 把后端推过来的在线列表映射成一个 Set，查找 O(1)
const onlineSet = computed(() =>
  new Set(onlineUsers.value.map(u => String(u.id)))
)

  // const filteredFriends = computed(() => {
  //   const query = searchQuery.value.toLowerCase()
  //   return friends.value.filter(friend =>
  //     friend.name.toLowerCase().includes(query)
  //   )
  // })

const displayedFriends = computed(() => {
  // 先做名字搜索过滤
  const query = searchQuery.value.toLowerCase()
  const filtered = friends.value.filter(f =>
    f.name.toLowerCase().includes(query)
  )

  // 再排序：自己最前 → 在线靠前 → 离线靠后
  return filtered.slice().sort((a, b) => {
    // 1. 自己最前
    if (String(a.id) === currentUserId) return -1
    if (String(b.id) === currentUserId) return 1

    // 2. 在线排前、离线排后
    const aOnline = onlineSet.value.has(String(a.id))
    const bOnline = onlineSet.value.has(String(b.id))
    if (aOnline !== bOnline) {
      return aOnline ? -1 : 1
    }

    // 3. 否则保持原序
    return 0
  })
})

// userStore.username = displayedFriends.value[0].name;

// 群聊的搜索
const filteredGroups = computed(() => {
  const query = searchQuery.value.toLowerCase()
  return groups.value.filter(group =>
    group.name.toLowerCase().includes(query)
  )
})

// 聊天功能
const currentChat = ref(friends.value[0]);
const messageInput = ref('')
const currentGroup = ref(groups.value[0]) // 新增：当前群聊对象

// 当前聊天消息
const currentMessages = computed(() => {
  if (currentNav.value === 'chat') {
    return messages.value.get(currentChat.value.id) || []  // 好友聊天消息
  } else if (currentNav.value === 'contacts') {
    return groupMessages.value.get(currentGroup.value.id) || []  // 群聊消息
  }
  return [] // 默认返回空消息

})

const showAddGroupDialog = () => {
// 根据群名的首字母生成群头像
if (groupName.value) {
    const firstLetter = groupName.value.charAt(0).toUpperCase();  // 获取首字母
    groupAvatar.value = generateGroupAvatar(firstLetter);  // 根据首字母生成头像
  } else {
    groupAvatar.value = defaultAvatar;  // 如果没有群名，使用默认头像
  }

  // 显示对话框
  isAddGroupDialogVisible.value = true;
}

const generateGroupAvatar = (letter) => {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  const size = 100;  // 设置头像的大小
  canvas.width = size;
  canvas.height = size;

  // 设置背景色和文字颜色
  const backgroundColors = ['#FF7F7F', '#FFD700', '#32CD32', '#1E90FF', '#8A2BE2'];
  const backgroundColor = backgroundColors[Math.floor(Math.random() * backgroundColors.length)];

  ctx.fillStyle = backgroundColor;
  ctx.fillRect(0, 0, size, size);

  ctx.fillStyle = '#FFFFFF';
  ctx.font = '40px Arial';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillText(letter, size / 2, size / 2);  // 在画布中间写字

  return canvas.toDataURL();  // 返回图像的 Data URL
}

const handleConfirm = () => {
  // 创建新的群聊
  if (!groupName.value) {
    alert('请输入群名');
    return;
  }


  groups.value.push({
    id: groups.value.length + 1,
    name: groupName.value,
    avatar: groupAvatar.value
  });

  // 清理状态并关闭对话框
  groupName.value = '';
  isAddGroupDialogVisible.value = false;
}

// 消息数据
const messages = ref(new Map()) // 好友聊天消息
const groupMessages = ref(new Map()) // 群聊消息




// import { c } from 'vite/dist/node/moduleRunnerTransport.d-DJ_mE5sf'

const FILE_DOWNLOAD = ref({
  type: "FILE_DOWNLOAD",
  payload: {
    "senderId": "",
    "targetId": "",
    "content": ""
  },
  timestamp: new Date().toISOString() // 确保时间戳有实际值
});

const fileDownloadState = ref({
receiving: false,    // 是否正在接收文件
fileName: '',        // 文件名
fileSize: 0,         // 文件总大小
receivedSize: 0,     // 已接收字节数
chunks: []           // 存储接收到的二进制块
})

const showFileUploadModal = ref(false)
const selectedFile = ref(null);
const CHUNK_SIZE = 60 * 1024 // 60KB分块

const getFileData = (fileName) => {
FILE_DOWNLOAD.value.payload.content = fileName
socket.send(JSON.stringify(FILE_DOWNLOAD.value));
}

function downloadFile()  {
  const { fileName, chunks } = fileDownloadState.value

  // 合并数据
  const blob = new Blob(chunks, { type: 'application/octet-stream' })
  const url = URL.createObjectURL(blob)

  // 创建下载链接
  const link = document.createElement('a')
  link.href = url
  link.download = fileName
  document.body.appendChild(link)
  link.click()

  // 清理资源
  document.body.removeChild(link)
  URL.revokeObjectURL(url)

  console.log(`文件下载完成: ${fileName}`)
}

// 选择文件
const handleFileSelect = (event) => {
  selectedFile.value = event.target.files[0];
};

// 上传文件
const uploadFile = async () => {
  if (!selectedFile.value) {
    console.error('No file selected!');
    return;
  }
  // 1. 发送元数据
  const metadata = {
    type: 'FILE_UPLOAD',
    fileName: selectedFile.value.name,
    fileSize: selectedFile.value.size,
    timestamp: new Date().toISOString(),
  };
  socket.send(JSON.stringify(metadata));

  // 5. 分块发送二进制文件数据
  const fileReader = new FileReader();
  let offset = 0;

  fileReader.onload = (e) => {
    const chunk = e.target.result;
    socket.send(chunk);
    offset += chunk.byteLength;

    if (offset < selectedFile.value.size) {
      readNextChunk();
    } else {
      resetUploadState(); // 上传完毕，重置 UI 状态
    }
  };

  const readNextChunk = () => {
    const slice = selectedFile.value.slice(offset, offset + CHUNK_SIZE);
    fileReader.readAsArrayBuffer(slice);
  };

  readNextChunk();

};

// 关闭文件弹窗并重置状态
const resetUploadState = () => {
  showFileUploadModal.value = false; // 关闭弹窗
  // 发送文件消息
  messageInput.value = selectedFile.value.name
  if (currentNav.value === 'chat') {
    sendMessage('FILE');
  } else if (currentNav.value === 'contacts') {
    sendGroupMessage('FILE');
  }
  selectedFile.value = null;         // 清空已选文件
};

const showEmojiPicker = ref(false)
const selectedEmoji = ref('')
const messageInputRef = ref(null) // textarea的DOM引用

// 表情列表
const emojiList = ref([
  '😀', '🤪', '😄', '😁', '😆', '😅',
  '😂', '🤣', '😊', '😇', '🙂', '🙃',
  '😉', '😌', '😍', '🥰', '😘', '😗',
  '🤭', '🤗', '🤨', '🫥', '🫡', '🤔',
  '🤑', '😋', '😐', '🤤', '🥵', '🤓',
  '😨', '😰', '🥹', '😤', '🤡', '💩'
])

const openEmojiPicker = () => {
  showEmojiPicker.value = true
}

const closeEmojiPicker = () => {
  showEmojiPicker.value = false
  selectedEmoji.value = ''
}

const selectEmoji = (emoji) => {
  selectedEmoji.value = emoji
}

const confirmSelection = () => {
  if (selectedEmoji.value) {
    insertEmoji(selectedEmoji.value);
    closeEmojiPicker()
  }
}

const insertEmoji = (emoji) => {
  const textarea = messageInputRef.value
  const startPos = textarea.selectionStart
  const endPos = textarea.selectionEnd

  // 在光标位置插入emoji
  messageInput.value =
    messageInput.value.substring(0, startPos) +
    emoji +
    messageInput.value.substring(endPos)

  // 调整光标位置到插入内容之后
  nextTick(() => {
    textarea.focus()
    const newPos = startPos + emoji.length
    textarea.setSelectionRange(newPos, newPos)
  })
}









// 发送消息
const messageContainer = ref(null)

const sendMessage = (type) => {
  const content = messageInput.value.trim()
  if (!content) return

  // todo:we should confirm this id when we select currentChatObject
  SINGLE_MESSAGE_Data.value.payload.senderId=idStore.id;
  SINGLE_MESSAGE_Data.value.payload.targetId=currentChat.value.id;
  SINGLE_MESSAGE_Data.value.payload.content=content;
  SINGLE_MESSAGE_Data.value.payload.type=type;

  socket.send(JSON.stringify(SINGLE_MESSAGE_Data.value));
  // console.log(SINGLE_MESSAGE_Data.value);

  const message = {
    type: 'sent',
    content,
    time: new Date().toISOString(),
    messageType: type,
    sender: userStore.username,
    avatar: userAvatar.value
  }

  //set the message box
  const chatMessages = messages.value.get(currentChat.value.id) || []
  messages.value.set(currentChat.value.id, [...chatMessages, message])


  messageInput.value = '';

  // 滚动到底部
  nextTick(() => {
    if (messageContainer.value) {
      messageContainer.value.scrollTop = messageContainer.value.scrollHeight
    }
  })

  // TODO: 发送消息到服务器
}

// 模拟接收消息
const simulateResponse = (content,from_id,type) => {
  setTimeout(() => {
    const sendMsgChat = ref(friends.value[0]);
    console.log(from_id);
    sendMsgChat.value = friends.value.find(friend => friend.id === from_id);
    console.log(sendMsgChat.value);

    const message = {
      type: 'received',
      content: content,
      time: new Date().toISOString(),
      messageType: type,
      sender: sendMsgChat.value.name,
      avatar: sendMsgChat.value.avatar
    }

    const chatMessages = messages.value.get(sendMsgChat.value.id) || []
    messages.value.set(sendMsgChat.value.id, [...chatMessages, message])

    console.log(chatMessages);

    // 滚动到底部
    nextTick(() => {
      if (messageContainer.value) {
        messageContainer.value.scrollTop = messageContainer.value.scrollHeight
      }
    })
  }, 1000)
}











const RoomMsgData = ref({
  type: "ROOM_MESSAGE",
  payload: {
    "roomId": "1",
    "senderId": "",
    "content": "",
    "type": ""
  },
  timestamp: new Date().toISOString() // 确保时间戳有实际值
});
const JOIN_ROOM_Data = ref({
  type: "JOIN_ROOM",
  payload: {
    "roomId": "1"
  },
  timestamp: new Date().toISOString() // 确保时间戳有实际值
});


const sendGroupMessage = (type)=>{
  const content = messageInput.value.trim()
  if (!content) return

  // todo:we should confirm this id when we select currentChatObject
  RoomMsgData.value.payload.roomId= currentGroup.value.id;
  RoomMsgData.value.payload.senderId=idStore.id;
  RoomMsgData.value.payload.content= content ;
  RoomMsgData.value.payload.type = type;


  socket.send(JSON.stringify(RoomMsgData.value));
  // console.log(SINGLE_MESSAGE_Data.value);

  const message = {
    type: 'sent',
    content,
    time: new Date().toISOString(),
    messageType: type,
    sender: userStore.username,
    avatar: userAvatar.value
  }
  //set the message box
  const chatMessages = groupMessages.value.get(currentGroup.value.id) || []
  groupMessages.value.set(currentGroup.value.id, [...chatMessages, message])
  messageInput.value = '';

  // 滚动到底部
  nextTick(() => {
    if (messageContainer.value) {
      messageContainer.value.scrollTop = messageContainer.value.scrollHeight
    }
  })
}

//RoomMsgDTO(roomId=1, senderId=1, content=asdason)
// 接收group消息
const getGroupMessage = (roomId,senderId,content,type) => {
  // groupMessages.value.clear();
  setTimeout(() => {
    const sendMsgChat = ref(friends.value[0]);
    //todo search in group member
    sendMsgChat.value = friends.value.find(friend => friend.id === senderId);
    console.log(sendMsgChat.value);

    const message = {
      type: 'received',
      content: content,
      time: new Date().toISOString(),
      messageType: type,
      sender: sendMsgChat.value.name,
      avatar: sendMsgChat.value.avatar
    }

    const chatMessages = groupMessages.value.get(roomId) || []
    groupMessages.value.set(roomId, [...chatMessages, message])
    console.log(chatMessages);

    // 滚动到底部
    nextTick(() => {
      if (messageContainer.value) {
        messageContainer.value.scrollTop = messageContainer.value.scrollHeight
      }
    })
  }, 20)
}
// 选择群聊
const selectGroup = (group) => {
  messageInput.value='';
  currentGroup.value = group
  if (!groupMessages.value.has(group.id)) {
    groupMessages.value.set(group.id, [])
  }
  // groupMessages.value.set(group.id, 1)
  JOIN_ROOM_Data.value.payload.roomId = currentGroup.value.id;
  socket.send(JSON.stringify(JOIN_ROOM_Data.value));
}
//                RoomMsgDTO(roomId=1, senderId=1, content=asdason)


// 消息时间显示逻辑
const showMessageTime = (message, index) => {
  if (index === 0) return true
  const prevMessage = currentMessages.value[index - 1]
  return new Date(message.time) - new Date(prevMessage.time) > 5 * 60 * 1000 // 5分钟显示一次时间
}

const formatMessageTime = (time) => {
  const date = new Date(time)
  return `${date.getMonth() + 1}月${date.getDate()}日 ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`
}

// 工具栏功能
const handleToolClick = (tool) => {
  // TODO: 实现工具栏功能
  console.log('点击工具：', tool.name)
  if (tool.name === 'file') {
    //弹出一个弹窗,弹窗中上传文件
    showFileUploadModal.value = true
    console.log(showFileUploadModal.value);
  } else if (tool.name === 'emoji') {
    openEmojiPicker();
  }
  //  if(tool.name === 'image') {
  //    getFileData();
  //  }
}

const sendLoginRequest = () => {
  return new Promise((resolve, reject) => {
    console.log("重新登录使用的凭据：", {
      username: userStore.username,
      password: userStore.password
    });
    const loginData = {
      type: "LOGIN",
      payload: {
        username: userStore.username,
        password: userStore.password
      },
      timestamp: new Date().toISOString()
    };
    socket.send(JSON.stringify(loginData));
    // 添加一次性的消息监听器来处理登录响应
    const loginHandler = (event) => {
      const response = JSON.parse(event.data);
      if (response.responseMsg === "登录成功") {
        console.log("重新登录成功");
        idStore.setId(response.data); // 确保设置用户ID
        socket.removeEventListener('message', loginHandler);
        resolve();
      } else if (response.responseMsg === "用户名或密码错误") {
        console.log("重新登录失败：用户名或密码错误");
        alert("重新登录失败：用户名或密码错误，请重新登录");
        router.push('/login');
        socket.removeEventListener('message', loginHandler);
        reject(new Error("登录失败"));
      }
    };

    socket.addEventListener('message', loginHandler);
    socket.send(JSON.stringify(loginData));
  });
};

// 搜索功能
const handleSearch = () => {
  // 实时搜索，已通过computed实现
}

// 初始化
// onMounted(() => {
//   // 初始化第一个聊天
//   selectChat(friends.value[0])
// })
onMounted(() => {
  socket.addEventListener('message', messageHandler);
  const initializeChat = async () => {
    try {
      await sendLoginRequest(); // 等待登录完成
      socket.send(JSON.stringify({
        type: "REQUEST_ONLINE_USERS",
        payload: {},
        timestamp: new Date().toISOString()
      }));

    socket.send(JSON.stringify({
      type: "GET_UNREAD_COUNTS",
      payload: { userId: parseInt(idStore.id) }
    }));
      // 只有在登录成功后才选择第一个聊天
      selectChat(friends.value[0]);
    } catch (error) {
      console.error("初始化聊天失败:", error);
    }
  };

  if (socket.readyState === WebSocket.OPEN) {
    initializeChat();
  } else {
    socket.addEventListener('open', initializeChat);
  }
  //getHistoriesMessage
});

function messageHandler(event) {
  try {
    const response = JSON.parse(event.data)
    console.log('[WS 收到]', response.responseMsg, response.data)

    switch (response.responseMsg) {
      case 'UNREAD_COUNTS':
        console.log('>> 收到未读统计，更新 unreadCounts：', response.data)
        Object.assign(unreadCounts, response.data)
        console.log('>> unreadCounts 当前状态：', unreadCounts)
        break

        case 'SINGLE_MESSAGE': {
      const msg = response.data
      const senderId = msg.senderId
      const targetId = msg.targetId

      // 只处理“发给我的”消息
      if (targetId === parseInt(idStore.id)) {

        // 1) 把它 push 进本地消息列表
        if (!messages.value.has(senderId)) {
          messages.value.set(senderId, [])
        }
        messages.value.get(senderId).push(msg)

        // 2) 如果当前聊的不是这个人，就 ++ 未读计数
        if (currentChat.value?.id !== senderId) {
          unreadCounts[senderId] = (unreadCounts[senderId] || 0) + 1
        }
      }
      break
    }

      // …你原来对 SINGLE_MESSAGE、HISTORIES_MESSAGE_ACK、GET_USER_LIST_ACK 等的处理…

      default:
        break
    }
  } catch (e) {
    console.error(e)
  }
}

// 在线用户数据
const onlineUsers = ref([]);

// 检查用户是否在线
const isUserOnline = (userId) => {
  return onlineUsers.value.some(u => u.id === String(userId));
}
  // 初始化第一个聊天
  if (socket.readyState === WebSocket.OPEN) {
    sendLoginRequest();
    console.log("重新登录成功");
  } else {
    // 如果连接未建立，等待连接建立后发送
    socket.addEventListener('open', () => {
      sendLoginRequest();
    });
    console.log("重新登录失败");
  }

  selectChat(friends.value[0])




</script>

<style scoped>
/* 保持原有的样式 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.chat-app {
  font-family: 'Microsoft YaHei', sans-serif;
  background-color: #f5f5f5;
  height: 100vh;
  width: 100vw;
  display: flex;
  overflow: hidden;
  width: 100%;
}

/* 左侧主导航栏 */
.main-sidebar {
  width: 100px;
  background-color: #2c3e50;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px 0;
  position: fixed;
  left: 92px;
  z-index: 10;
}

/* .main-sidebar .avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  overflow: hidden;
  margin-bottom: 30px;
} */

.main-sidebar .avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: #3498db;
  display: flex;
  flex-direction: column; /* 垂直排列 */
  justify-content: center;
  align-items: center; /* 水平居中 */
  color: #fff;
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 5px;
}


.avatar-text {
  /* 确保文本居中显示 */
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}
.avatar-name {
  margin-top: 0px; /* 添加顶部间距 */
  font-size: 20px;
  color: #fff;
  text-align: center; /* 确保文本居中 */
  margin-bottom: 25px;
}

.main-sidebar .avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.main-sidebar .nav-item {
  width: 80px;
  height: 80px;
  margin-bottom: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  border-radius: 8px;
  transition: background-color 0.3s;
}

.main-sidebar .nav-item:hover {
  background-color: #34495e;
}

.main-sidebar .nav-item.active {
  background-color: #3498db;
}

.main-sidebar .nav-item img {
  width: 24px;
  height: 24px;
  filter: invert(100%);
}

/* 退出登录文字样式 */
.main-sidebar .nav-item .logout-text {
  color: #ff0000;
  font-weight: bold;
  font-size: 14px;
}

/* 好友列表侧边栏 */
.friend-sidebar {
  width: 250px;
  background-color: #f0f2f5;
  height: 100vh;
  border-right: 1px solid #e0e0e0;
  display: flex;
  flex-direction: column;
  position: fixed;
  left: 194px;
  top: 0;
}

.search-bar {
  padding: 15px;
  border-bottom: 1px solid #e0e0e0;
}

.search-bar input {
  width: 100%;
  padding: 8px 12px;
  border: none;
  border-radius: 4px;
  background-color: #e6e6e6;
  font-size: 14px;
  outline: none;
}

.friend-list {
  flex: 1;
  overflow-y: auto;
}

.friend-item {
  padding: 12px 15px;
  display: flex;
  align-items: center;
  cursor: pointer;
  transition: background-color 0.2s;
}

.friend-item:hover {
  background-color: #e6e6e6;
}

.friend-item.active {
  background-color: #e6e6e6;
}

/* .friend-avatar {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  overflow: hidden;
  margin-right: 10px;
} */

.friend-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: #3498db;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  font-size: 18px;
  font-weight: bold;
  margin-right: 10px;
}


.context-menu {
  position: fixed;
  background: white;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-shadow: 0 2px 5px rgba(0,0,0,0.2);
  z-index: 1000;
}

.context-menu-item {
  padding: 8px 12px;
  cursor: pointer;
  color: #333;
  font-weight: 500;
}

.context-menu-item:hover {
  background-color: #f5f5f5;
}

.friend-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.friend-info {
  flex: 1;
}

.friend-name {
  font-size: 14px;
  color: #333;
  margin-bottom: 4px;
}

/* 聊天区域 */
.chat-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: #fff;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  position: fixed;
  width: 56%;
  left: 444px;
}

.chat-header {
  height: 60px;
  padding: 0 20px;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #e0e0e0;
  background-color: #fff;
}

.chat-title {
  font-size: 16px;
  font-weight: bold;
  color: #333;
}

.chat-messages {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  background-color: #f5f5f5;
  display: flex;
  flex-direction: column;
}

.message {
  margin-bottom: 15px;
  display: flex;
  width: 100%;
}

/* .message-avatar {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  overflow: hidden;
  margin-right: 10px;
} */

.message-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: #3498db; /* 添加蓝色背景 */
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  font-size: 18px;
  font-weight: bold;
  margin-right: 0px;
}

.message-avatar-container {
  display: flex;
  flex-direction: column; /* 垂直排列 */
  align-items: center; /* 水平居中 */
  justify-content: center; /* 垂直居中 */
  margin-right: 0;
}

.message-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.message-sender {
  font-size: 12px;
  color: #666;
  text-align: center;
  margin-top: 1px;
}

.message-content {
  max-width: 60%;
  min-width: 100px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
}

.message-time {
  font-size: 12px;
  color: #999;
  margin-bottom: 5px;
  text-align: center;
}

.message-bubble {
  padding: 10px 15px;
  border-radius: 4px;
  font-size: 14px;
  position: relative;
  word-break: break-word;
  display: inline-block;
  max-width: 100%;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.message.received .message-bubble {
  background-color: #fff;
  color: #333;
  border-top-left-radius: 0;
}

.message.sent {
  flex-direction: row-reverse;
}

.message.sent .message-avatar {
  margin-right: 0;
  margin-left: 5px;
}

.message.sent .message-bubble {
  background-color: #95ec69;
  color: #333;
  border-top-right-radius: 0;
}

.chat-input {
  height: 150px;
  border-top: 1px solid #e0e0e0;
  background-color: #fff;
  display: flex;
  flex-direction: column;
}

.input-toolbar {
  height: 40px;
  padding: 0 20px;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #f0f0f0;
}

.input-toolbar button {
  background: none;
  border: none;
  cursor: pointer;
  margin-right: 15px;
  opacity: 0.7;
  transition: opacity 0.2s;
}

.input-toolbar button:hover {
  opacity: 1;
}

.input-toolbar button img {
  width: 20px;
  height: 20px;
}

.input-area {
  flex: 1;
  padding: 10px 20px;
  position: relative;
}

.input-area textarea {
  width: 100%;
  height: 100%;
  border: none;
  resize: none;
  outline: none;
  font-size: 14px;
  font-family: 'Microsoft YaHei', sans-serif;
}

.send-btn {
  position: absolute;
  right: 20px;
  bottom: 10px;
  padding: 5px 15px;
  background-color: #95ec69;
  color: #333;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.send-btn:hover {
  background-color: #86d35f;
}

/* 群聊列表 */
.group-list {
  flex: 1;
  overflow-y: auto;
  padding: 10px 15px; /* 给群聊列表增加一些内边距 */
}

.group-item {
  padding: 12px 15px;
  display: flex;
  align-items: center;
  cursor: pointer;
  transition: background-color 0.2s;
  border-radius: 4px;  /* 增加圆角样式 */
}

.group-item:hover {
  background-color: #e6e6e6; /* 增加悬停效果 */
}

.group-item.active {
  background-color: #e6e6e6; /* 激活状态 */
}

.group-avatar {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  overflow: hidden;
  margin-right: 10px;
}

.group-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.group-info {
  flex: 1;
}

.group-name {
  font-size: 14px;
  color: #333;
  margin-bottom: 4px;
}

.add-group-dialog {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 1000;
}

.dialog-content {
  background: #fff;
  padding: 20px;
  border-radius: 8px;
  width: 300px;
  text-align: center;
}

.group-avatar img {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  margin-bottom: 20px;
}

.group-name-input input {
  width: 100%;
  padding: 10px;
  margin-bottom: 20px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.dialog-footer button {
  margin: 5px;
  padding: 10px 20px;
  border: none;
  background-color: #4CAF50;
  color: #fff;
  border-radius: 4px;
  cursor: pointer;
}

.dialog-footer button:hover {
  background-color: #45a049;
}


.modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}

.modal-content {
  position: relative;
  background: white;
  padding: 20px;
  border-radius: 8px;
  min-width: 400px;
}

.close-btn {
  position: absolute;
  right: 15px;
  top: 10px;
  cursor: pointer;
  font-size: 24px;
  color: #666;
  transition: color 0.2s;
}

.close-btn:hover {
  color: #333;
}

/* Emoji专属样式 */
.emoji-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
  margin: 20px 0;
  max-height: 300px;
  overflow-y: auto;
}

.emoji-item {
  cursor: pointer;
  font-size: 24px;
  padding: 8px;
  text-align: center;
  transition: all 0.2s;
  border-radius: 4px;
}

.emoji-item:hover {
  background: #f0f0f0;
  transform: scale(1.2);
}


.friend-item {
  position: relative;
}

.unread-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-block;
  min-width: 18px;
  height: 18px;
  line-height: 18px;
  font-size: 12px;
  color: #fff;
  background-color: #f56c6c;
  border-radius: 50%;
  text-align: center;
  padding: 0 4px;
}

</style>
currentNav.value = 'contacts'
